package com.syblood.app.camera.watermark.render;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.SurfaceTexture;
import android.opengl.EGL14;
import android.opengl.GLSurfaceView;
import android.util.Log;

import com.syblood.app.camera.callback.ICameraSurfaceRenderCallback;
import com.syblood.app.camera.watermark.utils.GlesUtil;
import com.syblood.app.utils.ConstantsUtils;
import com.syblood.app.utils.LogUtil;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

/**
 * @CreateTime : 2022/11/15
 * @Author : JiChangkong
 * @Description :
 */
public class CameraSurfaceRender implements GLSurfaceView.Renderer {
    private final static String TAG = ConstantsUtils.TAG_HEAD + CameraSurfaceRender.class.getSimpleName();
    private ICameraSurfaceRenderCallback mCallback;
    private RenderDrawerGroups mRenderGroups;
    private int width, height;
    private int mCameraTextureId1;
    private int mCameraTextureId2;

    private SurfaceTexture mCameraTexture1;
    private SurfaceTexture mCameraTexture2;

    private int mOriginalTextureId = 0;
    private float[] mTransformMatrix;
    private long timestamp;

    public CameraSurfaceRender(Context context) {
        this.mRenderGroups = new RenderDrawerGroups(context);
        mTransformMatrix = new float[16];
    }

    @Override
    public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {
        Log.d(TAG, "onSurfaceCreated mCallback " + mCallback);

        Bitmap bitmap = Bitmap.createBitmap(1920, 1080, Bitmap.Config.RGB_565);

        bitmap.eraseColor(Color.parseColor("#808080"));//填充颜色
        mOriginalTextureId = GlesUtil.loadBitmapTexture(bitmap);

        initCameraTexture();


        mRenderGroups.setInputTexture(mOriginalTextureId);
        mRenderGroups.create();
        mRenderGroups.setCameraTexture(mCameraTextureId1, mCameraTextureId2);
        Log.d(TAG, "onSurfaceCreated mOriginalTextureId = " + mOriginalTextureId);
        if (mCallback != null) {
            mCallback.onCreate();
        }
    }

    public void initCameraTexture() {
        mCameraTextureId1 = GlesUtil.createCameraTexture();
        mCameraTexture1 = new SurfaceTexture(mCameraTextureId1);
        mCameraTexture1.setOnFrameAvailableListener(new SurfaceTexture.OnFrameAvailableListener() {
            @Override
            public void onFrameAvailable(SurfaceTexture surfaceTexture) {
                Log.d(TAG, "mCameraTexture1 onFrameAvailable = " + surfaceTexture);
                if (mCallback != null) {
                    mCallback.onRequestRender();
                }
            }
        });
        mCameraTextureId2 = GlesUtil.createCameraTexture();
        mCameraTexture2 = new SurfaceTexture(mCameraTextureId2);
        mCameraTexture2.setOnFrameAvailableListener(new SurfaceTexture.OnFrameAvailableListener() {
            @Override
            public void onFrameAvailable(SurfaceTexture surfaceTexture) {
                Log.d(TAG, "mCameraTexture2 onFrameAvailable = " + surfaceTexture);
                if (mCallback != null) {
                    mCallback.onRequestRender();
                }
            }
        });
        Log.d(TAG, "onSurfaceCreated mCameraTextureId1 = " + mCameraTextureId1 + " , mCameraTexture1 = " + mCameraTexture1);
        Log.d(TAG, "onSurfaceCreated mCameraTextureId2 = " + mCameraTextureId2 + " , mCameraTexture2 = " + mCameraTexture2);
    }

    @Override
    public void onSurfaceChanged(GL10 gl10, int width, int height) {
        Log.d(TAG, "onSurfaceChanged mCallback " + mCallback);
        Log.d(TAG, "onSurfaceChanged width " + width + " , height = " + height);
        this.width = width;
        this.height = height;
        mRenderGroups.surfaceChangedSize(width, height);
        LogUtil.d("currentEGLContext: " + EGL14.eglGetCurrentContext().toString());
        if (mCallback != null) {
            mCallback.onChanged(width, height);
        }
    }

    private long lastCamera1Timestamp = -1;
    private long lastCamera2Timestamp = -1;

    @Override
    public void onDrawFrame(GL10 gl10) {
//        if (mCameraTexture1 != null) {
//            mCameraTexture1.updateTexImage();
//            long timestamp = mCameraTexture1.getTimestamp();
//            if (timestamp > lastCamera1Timestamp) {
//                mCameraTexture1.getTransformMatrix(mTransformMatrix);
//                mRenderGroups.draw(timestamp, mTransformMatrix, 1);
//                lastCamera1Timestamp = timestamp;
//            }
//        }
//        if (mCameraTexture2 != null) {
//            mCameraTexture2.updateTexImage();
//            long timestamp = mCameraTexture2.getTimestamp();
//            if (timestamp > lastCamera2Timestamp) {
//                mCameraTexture2.getTransformMatrix(mTransformMatrix);
//                mRenderGroups.draw(timestamp, mTransformMatrix, 2);
//                lastCamera2Timestamp = timestamp;
//            }
//        }
        if (mCameraTexture1 != null && mCameraTexture2 != null) {
            mCameraTexture1.updateTexImage();
            long timestamp1 = mCameraTexture1.getTimestamp();

            mCameraTexture2.updateTexImage();
            long timestamp2 = mCameraTexture2.getTimestamp();

            if (timestamp1 > lastCamera1Timestamp) {
                mRenderGroups.draw(timestamp1, null, 2);
                lastCamera1Timestamp = timestamp1;
            } else if (timestamp2 > lastCamera2Timestamp) {
                mRenderGroups.draw(timestamp2, null, 2);
                lastCamera2Timestamp = timestamp2;
            }


        }
        if (mCallback != null) {
            mCallback.onDraw();
        }
    }

    public SurfaceTexture getCamera1SurfaceTexture() {
        return mCameraTexture1;
    }

    public SurfaceTexture getCamera2SurfaceTexture() {
        return mCameraTexture2;
    }

    public void setCallback(ICameraSurfaceRenderCallback mCallback) {
        this.mCallback = mCallback;
    }

    public void releaseSurfaceTexture() {
        if (mCameraTexture1 != null) {
            mCameraTexture1.release();
            mCameraTexture1 = null;
        }
        if (mCameraTexture2 != null) {
            mCameraTexture2.release();
            mCameraTexture2 = null;
        }
    }

    public void resumeSurfaceTexture() {
        initCameraTexture();
    }

    public void startRecord() {
        mRenderGroups.startRecord();
    }

    public void stopRecord() {
        mRenderGroups.stopRecord();
    }

    public boolean isRecording() {
        return mRenderGroups.isRecording();
    }

    public void destroy() {
        mRenderGroups.destroy();
    }
}
